
package pho.helper;

import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
 * @author Peter
 *
 * This is a helper class to encapsulate certain repeated actions to initialize 
 * a DOM correctly via JAXP and read an XML file as Document. It also provides
 * a helper to escape critical XML characters with the correct values. 
 */
public class XMLHelper
{
	private static DocumentBuilder docBuilder;
	
	/**
	 * loads an XML document from an InputStream and creates a Document object
	 * @param is the InputStream which provides the XML document
	 * @return a Document object or null if an exception occurred (XML is not well-formed, etc...)
	 */
	public static Document loadDocumentFromStream (InputStream is)
	{
		initializeDOMImplementation();
				
		Document document = null;
		try 
		{
			document = docBuilder.parse(is);
		} 
		catch (SAXException e) 
		{
		   System.err.println(e);
		} 
		catch (IOException e) 
		{
		   System.err.println(e);
		}
		catch (IllegalArgumentException e)
		{
			System.err.println(e);
		}
		return document;
	}

	/**
	 * initializes the DOM implementation that is set up via JAXP
	 */
	private static void initializeDOMImplementation ()
	{
		if (docBuilder == null) 
		{
			try
			{
				DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
				factory.setValidating(false);
				factory.setNamespaceAware(false);
				docBuilder = factory.newDocumentBuilder();
			} 
			catch (ParserConfigurationException e) 
			{
				System.out.println("The underlying parser does not support the requested features.");
			} 
			catch (FactoryConfigurationError e) 
			{
				System.out.println("Error occurred obtaining Document Builder Factory.");
			} 
			catch (Exception e) 
			{
				e.printStackTrace();
			}		
		}
	}	

	/**
	 * converts a string into a valid XML-escaped version of that string
	 * @param chars the string to be converted
	 * @return the converted string
	 */
	public static String xmlChars (String chars)
	{
		StringBuffer sb = new StringBuffer ();
		for (int i = 0; i < chars.length();i++)
		{
			switch (chars.charAt(i))
			{
				 case '&':
					sb.append("&amp;");
					break;
				 case '<':
					sb.append("&lt;");
					break;				 	
				 case '>':
					sb.append("&gt;");
					break;
				 case '\'':
				 	sb.append("&apos;");
				 	break;
				case '"':
				   sb.append("&quot;");
				   break;				   
				case 0x9:
				case 0xa:
				case 0xd:
					sb.append(chars.charAt(i));
					break;			
				default:
				 	if (chars.charAt(i) >= 0x20)
				 	{
						sb.append(chars.charAt(i));
				 	}
				 	else
				 	{
				 		System.out.println ("Skipping invalid character in Index");
				 	}
					break;
			}
		}
		return sb.toString();
	}

}
